package tesauro;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;

/**
 * Clase que representa una palabra y sus sinonimos dentro
 * del diccionario de sinonimos. La lista de sinonimos se almacena en
 * un TreeSet para mantenerlos ordenados y evitar repeticiones de sinonimos.
 * Los metodos de seteo de lista de sinonimos reciben como parametro una
 * List e internamente los metodos arman el TreeSet. Para los metodos de
 * obtencion de lista de sinonimos, estos regresan una lista que se genera a partir
 * del TreeSet original.
 * 
 * Dos instancias de esta clase son iguales si representan a la
 * misma palabra.
 * 
 * @author Demian
 */
public class EntradaDiccionario implements Serializable{
    private String palabra;
    private TreeSet<String> sinonimos;
    private static final long serialVersionUID = 33333L;
    
    public EntradaDiccionario(String palabra) {
        this.palabra = palabra.toLowerCase();
        this.sinonimos = new TreeSet();
    }
    
    public EntradaDiccionario(String palabra, List<String> sinonimos) {
        this(palabra);
        this.setSinonimos(sinonimos);
    }
    
    /**
     * Obtiene la palabra de la entrada.
     * 
     * @return
     */
    public String getPalabra() {
        return palabra;
    }
    
    /**
     * Setea la palabra de la entrada.
     * 
     * @param palabra
     */
    public void setPalabra(String palabra) {
        this.palabra = palabra.toLowerCase();
    }
    
    /**
     * Obtiene una copia de la lista de sinonimos.
     * 
     * @return lista copia de la lista de sinonimos o null si no tiene sinonimos.
     */
    public List<String> getSinonimos() {
        if(sinonimos == null || sinonimos.size() == 0) {
            return null;
        }
        
        return Collections.list(Collections.enumeration(sinonimos));
    }
    
    /**
     * Sete la lista de sinonimos para la entrada.
     * 
     * @param sinonimos lista de sinonimos.
     */
    public void setSinonimos(List<String> sinonimos) {
        ArrayList<String> sinonimosLowerCase = new ArrayList<String>(sinonimos.size());
        for(String sinonimo : sinonimos) {
            sinonimosLowerCase.add(sinonimo.toLowerCase());
        }
        
        this.sinonimos.clear();
        this.sinonimos.addAll(sinonimosLowerCase);
    }
    
    /**
     * Remueve de la lista de sinonimos el sinonimo indicado.
     * Si la lista no contiene el sinonimo ninguna accion se 
     * lleva a cabo.
     * 
     * @param sinonimo sinonimo a remover.
     */
     public void removeSinonimo(String sinonimo) {
         if(sinonimo == null) {
             return;
         }
         
         String lowerCase = sinonimo.toLowerCase();
        sinonimos.remove(lowerCase);
    }
     
     /**
      * Agrega a lista de sinonimos el sinonimo indicado.
      * Si el sinonimo ya existe ninguna accion se lleva a cabo.
      * 
      * @param sinonimo sinonimo a agregar.
      */
     public void addSinonimo(String sinonimo) {
         if(sinonimo == null) {
             return;
         }
         
         String lowerCase = sinonimo.toLowerCase();
         if(sinonimos != null && !sinonimos.contains(lowerCase)) {
             sinonimos.add(lowerCase);
         }
     }
     
     /**
      * Obtiene la cantidad de sinomis cargados
      * para la palabra.
      * 
      * @return cantidad de sinonimos de la palabra.
      */
     public int getCantidadDeSinonimos() {
         return sinonimos == null ? 0 : sinonimos.size();
     }
     
     /**
      * Dos objetos EntradaHash son iguales si sus respectivas
      * palabras que representan son iguales.
      * 
      * @param o instancis de EntradaHash.
      * @return true si las instancias son iguales, false si no los son.
      */
    public boolean equals(Object o) {
        if(o == null || !(o instanceof EntradaDiccionario)) {
            return false;
        }
        
        if(o == this) {
            return true;
        }
        
        return ((EntradaDiccionario)o).palabra.equals(palabra);
    }
    
    /**
     * El hashcode de una instancia es el hash code nativo de los
     * Strings de java.
     * 
     * @return hash code de la instancia.
     */
    @Override
    public int hashCode() {
        return palabra.hashCode();
    }
    
    @Override
    public String toString() {
        return "[" + palabra + ", " + sinonimos + "]";
    }
}